package ckw.database.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import ckw.utils.CustomComparator;
import core.database.AbstractEntity;
import core.database.ElectionStatus;

@Entity
@Table(name = "electionNode")
public class ElectionNode extends AbstractEntity {
	@ManyToOne(cascade = { CascadeType.DETACH })
	@JoinColumn(name = "node", insertable = true, updatable = true)
	private Node node;

	@ManyToOne
	@JoinColumn(name = "election")
	private Election election;

	@Column(name = "status", nullable = false)
	private ElectionStatus status = ElectionStatus.UNSTARTED;

	@OneToMany(mappedBy = "electionNode", fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE }, orphanRemoval = true)
	private List<AdministratorToken> administratorTokens = new ArrayList<AdministratorToken>();

	@OneToMany(mappedBy = "electionNode", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE }, orphanRemoval = true)
	private List<ElectionResidentVoter> voters = new ArrayList<ElectionResidentVoter>();

	public Node getNode() {
		return node;
	}

	public void setNode(Node node) {
		this.node = node;
		node.getElections().add(this);
	}

	public Election getElection() {
		return election;
	}

	public void setElection(Election election) {
		this.election = election;
		election.getNodes().add(this);
	}

	public List<AdministratorToken> getAdministratorTokens() {
		return administratorTokens;
	}

	public void setAdministratorTokens(List<AdministratorToken> administratorTokens) {
		this.administratorTokens = administratorTokens;
	}

	public List<ElectionResidentVoter> getVoters() {
		return voters;
	}

	public void setVoters(List<ElectionResidentVoter> voters) {
		this.voters = voters;
	}

	public ElectionStatus getStatus() {
		return status;
	}

	public void setStatus(ElectionStatus status) {
		this.status = status;
	}

	public List<Member> getMembers() {
		List<Member> members = new ArrayList<Member>();

		for (AdministratorToken token : administratorTokens) {
			members.add(token.getMember());
		}

		Collections.sort(members, new CustomComparator<Member>());

		return members;
	}

	@Override
	public String toString() {
		return super.toString() + " nodeName: " + node.getName() + " electionName: " + election.getName();
	}
}
